#include "animation.h"
#include "../file/config.h"
#include "../file/file.h"

using namespace TerraGE;

Animation::Animation(Bitmap_Manager *bm, string path, float sp, bool bidir, bool rep) {
    ALLEGRO_FS_ENTRY *directory;
    ALLEGRO_FS_ENTRY *file;
    vector<string> list;
    list.clear();

    directory = al_create_fs_entry(path.c_str());

    if (al_open_directory(directory)) {
        while ((file=al_read_directory(directory)) != NULL) {
            if (al_get_fs_entry_mode(file) & ALLEGRO_FILEMODE_ISFILE) list.push_back(al_get_fs_entry_name(file));
            al_destroy_fs_entry(file);
        }
        al_close_directory(directory);
        al_destroy_fs_entry(directory);

        for (vector<string>::iterator it=list.begin(); it!=list.end(); it++) {
            ALLEGRO_BITMAP *bit;
            bit = bm->Get_Bitmap(*it)->Get_Bit();
            if (bit) {
                if ((*it).find("diffuse") != string::npos) frames_diffuse.push_back(bit);
                if ((*it).find("normal") != string::npos) frames_normal.push_back(bit);
                if ((*it).find("height") != string::npos) frames_height.push_back(bit);
            }
        }
    }

    active = true;
    size = frames_diffuse.size();
    frame = 0;
    direction = 1;

    speed = sp;
    bidirectional = bidir;
    repeat = rep;
}


void Animation::Update(float timestep) {
    if (!active) return;

    frame += speed * timestep * (direction ? 1 : -1);
    if (frame >= size) {
        frame = size-1;
        if (bidirectional) direction = false;
        if (!bidirectional && repeat) frame = 0;

        if (!bidirectional && ! repeat) active=false;
    }
    if (frame < 0) {
        frame = 0;

        if (bidirectional && repeat) direction = true;
        else active = false;
    }

    actual_bit_diffuse = frames_diffuse[(int)frame];
    actual_bit_height = frames_height[(int)frame];
    actual_bit_normal = frames_normal[(int)frame];
}


void Animation::Start() {
    frame = 0;
    active = true;
    direction = true;
}

void Animation::Resume() {
    active = true;
}

void Animation::Stop() {
    active = false;
}

void Animation::Set_Frame_Percent(float f) {
    frame = f*size;
    if (frame < 0) frame = 0;
    if (frame >= size) frame = size-1;

    actual_bit_diffuse = frames_diffuse[(int)frame];
    actual_bit_height = frames_height[(int)frame];
    actual_bit_normal = frames_normal[(int)frame];
}

void Animation::Set_Frame(float f) {
    frame = f;
    if (frame < 0) frame = 0;
    if (frame >= size) frame = size-1;

    actual_bit_diffuse = frames_diffuse[(int)frame];
    actual_bit_height = frames_height[(int)frame];
    actual_bit_normal = frames_normal[(int)frame];
}

Animation::~Animation() {
}













Animation_Manager::Animation_Manager(Bitmap_Manager *bm, string path) {
    string nm=path + "animations.ini";
    if (File_Exists(nm)) {
        Config *cfg;
        cfg = new Config(nm);
        vector<string> list;
        list = cfg->Get_Sections();
        for (vector<string>::iterator it=list.begin(); it!=list.end(); it++) {
            Animation *an=new Animation(bm, path + *it + "/",
                                        cfg->Get_Float(*it, "Speed"),
                                        cfg->Get_Float(*it, "Bidirectional"),
                                        cfg->Get_Float(*it, "Repeat"));

            animations.push_back(an);
        }
        delete cfg;

        actual_animation = (*animations.begin());
    }
}


void Animation_Manager::Update(float timestep) {
    if (actual_animation) actual_animation->Update(timestep);
}

void Animation_Manager::Start() {
    if (actual_animation) actual_animation->Start();
}

void Animation_Manager::Resume()  {
    if (actual_animation) actual_animation->Resume();
}

void Animation_Manager::Stop()  {
    if (actual_animation) actual_animation->Stop();
}

void Animation_Manager::Set_Animation(string nm) {
}

void Animation_Manager::Set_Next_Animation(string nm) {
}


